<template>
  <div class="page-container">
    <!-- 筛选区域 -->
    <el-card>
      <el-input class="select-box" size="large" placeholder="请用户名称" v-model="username" />
      <el-button type="primary" :icon="Search" @click="selectList"> 查询 </el-button>
      <el-button @click="resetInput">清空</el-button>
    </el-card>

    <!-- 角色列表 -->
    <el-card class="box-card">
      <div>
        <el-button type="primary" @click="addUserBtn" v-power="'btn.User.add'"> 添加 </el-button>
        <el-button type="danger">批量删除</el-button>
      </div>

      <el-table :data="userList" border stripe width="100%" @selection-change="selectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column label="序号" type="index" width="88" />
        <el-table-column prop="username" label="用户名" width="150" />
        <el-table-column prop="nickName" label="用户昵称" width="150" />
        <el-table-column prop="roleName" label="角色列表" width="200" />
        <el-table-column prop="gmtCreate" label="创建时间" width="180" />
        <el-table-column prop="gmtModified" label="更新时间" width="180" />
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button
              v-power="'btn.User.assgin'"
              size="small"
              type="primary"
              :icon="InfoFilled"
              @click="setRoleBtn(row)"
            />
            <el-button
              v-power="'btn.User.update'"
              size="small"
              type="warning"
              :icon="Edit"
              @click="editUser(row)"
            />
            <el-button
              size="small"
              type="danger"
              :icon="Delete"
              v-power="'btn.User.remove'"
              @click="removeUser(row)"
            />
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        v-model:current-page="page"
        v-model:page-size="limit"
        :page-sizes="[5, 10, 15, 20]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 新增用户弹框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑用户信息' : '新增用户信息'"
      width="40%"
      align-center
      :before-close="handleClose"
    >
      <el-form ref="ruleFormRef" :model="userForm" :rules="userFormRules" label-width="100px">
        <el-form-item label="用户名" prop="username">
          <el-input type="text" v-model="userForm.username" />
        </el-form-item>
        <el-form-item label="用户昵称" prop="nickName">
          <el-input type="text" v-model="userForm.nickName" />
        </el-form-item>
        <el-form-item label="用户密码" prop="password">
          <el-input type="password" v-model="userForm.password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleClose">取消</el-button>
          <el-button type="primary" @click="confirm">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 设置角色 -->
    <el-dialog
      v-model="setRoleDialogVisible"
      title="设置角色"
      width="50%"
      align-center
      :before-close="setRoleClose"
    >
      <el-form label-width="100px">
        <el-form-item label="用户名">
          <el-input v-model="dialogUserName" :disabled="true" />
        </el-form-item>
        <el-form-item label="角色列表">
          <div class="selct-all">
            <el-checkbox
              :indeterminate="isIndeterminate"
              v-model="checkAll"
              @change="handleCheckAllChange"
            >
              全选
            </el-checkbox>
          </div>
          <el-checkbox-group v-model="assignRole" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="item in allRolesList" :key="item.id" :label="item.id">
              {{ item.roleName }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="setRoleConfirm">确定</el-button>
          <el-button @click="setRoleClose">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import { Search, InfoFilled, Edit, Delete } from '@element-plus/icons-vue'
import {
  reqAssignList,
  reqDelUser,
  reqSaveUser,
  reqUpdateUser,
  reqUserList,
  reqSetAssign
} from '@/api/userList'
import type { AllRolesList, IResUserItem, IUpdateUserParams } from '@/types/userList'
import {
  ElMessage,
  ElMessageBox,
  type CheckboxValueType,
  type FormInstance,
  type FormRules
} from 'element-plus'

// 需要筛选的角色名称
const username = ref('')
// 权限管理列表数据
const userList = ref<IResUserItem[]>([])

// 分页数据
const page = ref(1)
const limit = ref(5)
const total = ref(0)

// 新增、编辑弹框表单
const ruleFormRef = ref<FormInstance>()
// 展示新增、编辑弹框
const dialogVisible = ref(false)
// 新增、编辑弹框数据
const userForm = ref({
  username: '',
  password: '',
  nickName: ''
} as IUpdateUserParams)
// 新增、编辑弹框表单校验规则
const userFormRules = reactive<FormRules>({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 6, max: 10, message: '用户名在在 6 ~ 10 个字之间', trigger: 'blur' }
  ],
  nickName: [
    { required: true, message: '请输入用户昵称', trigger: 'blur' },
    { min: 6, max: 10, message: '用户昵称在 6 ~ 10 个字之间', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入用户密码', trigger: 'blur' },
    { min: 6, message: '用户密码最少 6 位', trigger: 'blur' }
  ]
})
// 是否是编辑
const isEdit = ref(false)

// 是否展示设置角色弹框
const setRoleDialogVisible = ref(false)
// 当前用户的名字
const dialogUserName = ref('')
// 当前用户的 id
const dialogUseId = ref('')

const checkAll = ref(false)
// 获取全部的角色列表
const allRolesList = ref<AllRolesList[]>([])
const assignRole = ref<string[]>([])
const isIndeterminate = ref(true)

// 处理角色的全选和全不选，获取全部的 id
const handleCheckAllChange = (val: CheckboxValueType) => {
  console.log(val)
  assignRole.value = val ? allRolesList.value.map((item) => item.id) : []
  isIndeterminate.value = false
}

// 批量删除
const selectionChange = (val: IUpdateUserParams[]) => {
  const ids = val.map((item) => item.id)

  console.log(ids)
}

// 获取更新后的角色 id
const handleCheckedCitiesChange = (val: CheckboxValueType[]) => {
  console.log(val)
  // 接收选择的角色数量
  const checkedCount = val.length
  // 判断是否是选择
  checkAll.value = checkedCount === allRolesList.value.length
  // 控制动画效果
  isIndeterminate.value = checkedCount > 0 && checkedCount < allRolesList.value.length

  // 获取选择的角色 id
  assignRole.value = val as string[]
}

// 显示设置角色弹框
const setRoleBtn = async (row: IUpdateUserParams) => {
  setRoleDialogVisible.value = true
  dialogUserName.value = row.nickName
  dialogUseId.value = row.id as string

  // 调用接口，传递参数，获取角色数据
  const res = await reqAssignList(row.id as number)

  if (res.code === 20000) {
    nextTick(() => {
      allRolesList.value = res.data.allRolesList
      assignRole.value = res.data.assignRoles.map((item) => item.id)
    })
  }
}

// 关闭设置角色弹框
const setRoleClose = function () {
  // 弹框展示的用户名 和 id 重置
  dialogUserName.value = ''
  dialogUseId.value = ''

  // 将数组重置
  allRolesList.value = []
  assignRole.value = []

  // 重置全选状态
  checkAll.value = false
  // 控制动画
  isIndeterminate.value = true

  // 隐藏弹框
  setRoleDialogVisible.value = false
}

// 设置角色
const setRoleConfirm = async () => {
  const res = await reqSetAssign(dialogUseId.value, assignRole.value.join(','))
  if (res.code === 20000) {
    // 执行关闭弹窗的操作
    setRoleClose()

    //给用户提示
    ElMessage.success('角色设置成功')

    // 重新获取数据列表
    getUserList()
  }
}

// 删除
const removeUser = (row: IUpdateUserParams) => {
  ElMessageBox.confirm('确认删除该用户?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      await reqDelUser(row.id as number)
      ElMessage({
        type: 'success',
        message: '商品删除成功'
      })
      getUserList()
    })
    .catch(() => {
      ElMessage.info('商品删除失败')
    })
}

// 点击新增的弹框
const addUserBtn = () => {
  // 展示弹框
  dialogVisible.value = true
  // 是否是编辑
  isEdit.value = false
}

// 点击编辑的按钮
const editUser = (row: IUpdateUserParams) => {
  // 展示弹框
  dialogVisible.value = true
  // 是否是编辑
  isEdit.value = true
  // 数据回显
  userForm.value = { ...row }
}

// 关闭弹框
const handleClose = () => {
  // 重置表单
  ruleFormRef.value?.resetFields()
  // 重置新增、编辑弹框的数据
  userForm.value = {
    username: '',
    password: '',
    nickName: ''
  } as IUpdateUserParams
  // 隐藏弹框
  dialogVisible.value = false
}

// 确定弹框
const confirm = () => {
  ruleFormRef.value?.validate(async (valid) => {
    // 表单验证失败
    if (!valid) return

    const res = isEdit.value
      ? await reqUpdateUser(userForm.value)
      : await reqSaveUser(userForm.value)

    if (res.code === 20000) {
      // 用户提示
      ElMessage.success(isEdit.value ? '编辑用户成功' : '新增用户成功')
      // 重新获取数据列表
      getUserList()
      // 隐藏弹框
      handleClose()
    }
  })
}

// 筛选用户列表
const selectList = () => {
  if (username.value.trim() === '') return
  getUserList()
}

// 清空筛选条件
const resetInput = () => {
  username.value = ''
  getUserList()
}

// page-size 改变时触发
const handleSizeChange = (val: number) => {
  limit.value = val
  getUserList()
}

// current-page 改变时触发
const handleCurrentChange = (val: number) => {
  page.value = val
  getUserList()
}

// 获取用户列表数据
const getUserList = async () => {
  // 调用接口，传递参数，获取用户列表数据
  const res = await reqUserList(page.value, limit.value, username.value)

  if (res.code === 20000) {
    userList.value = res.data.items
    total.value = res.data.total
  }
}

// 页面挂载完成后执行
onMounted(() => {
  getUserList()
})
</script>

<script lang="ts">
export default {
  name: 'UserList'
}
</script>

<style lang="scss" scoped>
.no-autofill-pwd {
  :deep(.el-input__inner) {
    -webkit-text-security: disc !important;
  }
}

.select-box {
  width: 200px;
  height: 34px;
  margin-right: 16px;
}

.box-card {
  margin-top: 14px;

  .el-table {
    margin-top: 18px;
  }

  .el-pagination {
    margin-top: 18px;
    display: flex;
    justify-content: center;
  }
}

.el-dialog {
  .el-dialog__body {
    .el-form {
      margin-right: 30px;
    }
  }
}

.selct-all {
  width: 100%;
  .el-checkbox:last-of-type {
    width: 100%;
  }
}
</style>
